﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using PROJECT_BOMBER.BLL.Events.Collisions;

namespace PROJECT_BOMBER.BLL
{
    public class Character : ElementMove
    {

        private int _score;

        public int Score
        {
            get { return _score; }
            set { _score = value; }
        }

        // OBSOLETE
        private float _rotation = 0;

        public float Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        public Vector2 CenterRotation = Vector2.Zero;

        ControllerStrategy _controller = null;

        public ControllerStrategy Controller
        {
            get { return _controller; }
            set { _controller = value; }
        }


        #region Constructeur

        /// <summary>
        /// Initializes a new instance of the <see cref="Character"/> class, and specify the position.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        public Character(int x, int y) : this(x,y,0,0)
        {
            CollisionStrategy = new GhostCollision();
            CollisionStrategy = new WinCollision();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Character"/> class, and specify the position, and the speed.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="speedx">The speedx.</param>
        /// <param name="speedy">The speedy.</param>
        public Character(int x, int y, int speedx, int speedy) : base(x,y)
        {
            Score = 0;
        }

        #endregion

        #region Limits

        // get and set the area's limits
        float _maxX = 0;
        public float MaxX
        {
            get { return _maxX; }
            set { _maxX = value; }
        }
        
        int _minX = 0;
        public int MinX
        {
            get { return _minX; }
            set { _minX = value; }
        }

        float _maxY = 0;
        public float MaxY
        {
            get { return _maxY; }
            set { _maxY = value; }
        }
        
        int _minY = 0;
        public int MinY
        {
            get { return _minY; }
            set { _minY = value; }
        }

        /// <summary>
        /// stop the character's speed in X or Y and replace him in function of the area's limits
        /// </summary>
        public void Limit()
        {
            if (Position.X >= MaxX && Speed.X > 0)
            {
                Speed = new Microsoft.Xna.Framework.Vector2(0, Speed.Y);
                Position =  new Vector2(MaxX, Position.Y);
            }

            else if (Position.X <= MinX && Speed.X < 0)
            {
                Speed = new Microsoft.Xna.Framework.Vector2(0, Speed.Y);
                Position = new Vector2(MinX, Position.Y);
            }

            if (-Position.Y >= MaxY && Speed.Y <= 0)
            {
                Speed = new Microsoft.Xna.Framework.Vector2(Speed.X, 0);
                //Position.Y = -MaxY;
                Position = new Vector2(-MaxY, Position.Y);

            }

            else if (-Position.Y - Height <= MinY && Speed.Y > 0)
            {

                if (Speed.Y >= Speedmax.Y / 2.5)
                {
                    Dead = true;
                }
                Speed = new Microsoft.Xna.Framework.Vector2(Speed.X, 0);
                Position = new Vector2(Position.X, MinY - Height);
                Onground++;
                Jump = 0;
                ActiveSpeedX = true;

            }
        }

        #endregion

        #region Updates

        /// <summary>
        /// list of actions to update at each refresh
        /// </summary>
        /// <param name="game">The game.</param>
        /// <param name="gametime">The gametime.</param>
        /// <param name="graphics">The graphics.</param>
        /// <param name="level">The level.</param>
        /// <param name="cam">The camera</param>
        /// <param name="list">The element's list in collision with the character</param>
        public void Update(Level level, List<ElementPhysique> list)
        {

            //CenterRotation = new Vector2(Width / 2, Height/2);

            MaxX = -Width + level.Width;
            MaxY = level.Height;

            #region Commandes
            if (!Dead)
            {
                Controller.Control(this);
            }
            #endregion

            #region redefinission position cases
            Case = new Rectangle(
                (int)Position.X,
                (int)Position.Y,
                (int)Width,
                (int)Height);


           // Positioncontrol = Position + Speed * (float)gametime.ElapsedGameTime.TotalSeconds;
           // Casecontrol = new Rectangle((int)Positioncontrol.X, (int)Positioncontrol.Y, (int)Width, (int)Height);

            Limit();

           // Positioncontrol = Position + Speed * (float)gametime.ElapsedGameTime.TotalSeconds;
          //  Casecontrol = new Rectangle((int)Positioncontrol.X, (int)Positioncontrol.Y, (int)Width, (int)Height);

            #endregion

            #region controle vitesse default

            if (Fly)
            {
                Speed = new Microsoft.Xna.Framework.Vector2(Speed.X, Speedmin.Y*2);
            }
            else if (Speed.Y < Speedmax.Y)
            {
                Speed = new Microsoft.Xna.Framework.Vector2(Speed.X, Speed.Y + Speedmin.Y * (Gravity / 10));
            }


            #endregion

            #region Commandes
            if (!Dead)
            {
                Controller.Control(this);
            }
            #endregion

            #region Collisions

            Onground = 0;
           // Positioncontrol = Position + Speed * (float)gametime.ElapsedGameTime.TotalSeconds;
            //Casecontrol = new Rectangle((int)Positioncontrol.X, (int)Positioncontrol.Y, (int)Width, (int)Height);

            //Collisions(list);

            foreach (ElementPhysique element in list)
            {
                element.CollisionStrategy.Collision(element, this);
            }
            #endregion

            if (Onground > 0)
            {
                Fly = false;
            }

            if (Fly)
            {
                //Case = new Rectangle((int)Position.X, (int)Position.Y - AnimationSprite.Fly().Definition.FrameSize.Y / 2, AnimationSprite.Fly().Definition.FrameSize.X / 2, AnimationSprite.Fly().Definition.FrameSize.Y);
                //Height = CurrentAnimation.Definition.FrameSize.Y;
            }
            else
            {
                //Case = new Rectangle((int)Position.X, (int)Position.Y, AnimationSprite.Face().Definition.FrameSize.X, AnimationSprite.Face().Definition.FrameSize.Y);
                //Height = AnimationSprite.Face().Definition.FrameSize.Y;
            }

            UpdateAnimation();

            Position += Speed * (float)Globals.GameTime.ElapsedGameTime.TotalSeconds;

            Onscreen();

            ChooseAnimation();

        }

        /// <summary>
        /// Calculate Collisions between each element in list and the character
        /// </summary>
        /// <param name="list">The element's list in collision with the character</param>
        public void Collisions(List<ElementPhysique> list)
        {
            foreach (ElementPhysique obj in list)
            {
                if (obj.GetType() == new Ventilateur(0, 0, 0, 0).GetType())
                {
                    Ventilateur element = obj as Ventilateur;
                    element.CollisionObjet(this);
                }
                else if (obj.GetType() == new Level(0,0).GetType())
                {
                    Level element = obj as Level;
                    element.CollisionObjet(this);
                }
               
            }
        }

        internal void ChooseAnimation()
        {



            if (Dead)
            {
                CurrentAnimation = Animations["dead"];
            }
            else if (Fly)
            {
                CurrentAnimation = Animations["fly"];
            }
            else if (Attack)
            {
                CurrentAnimation = Animations["attack"];
            }
            else if (Jump > 0)
            {
                if (Speed.Y < 0)
                {
                    CurrentAnimation = Animations["up"];
                }
                else
                {
                    CurrentAnimation = Animations["down"];
                }
            }
            else if (Speed.X < 0)
            {
                CurrentAnimation = Animations["left"];
            }
            else if (Speed.X > 0)
            {
                CurrentAnimation = Animations["right"];
            }
            else
            {
                CurrentAnimation = Animations["default"];
            }
        }


        #endregion



    }
}
